package com.xiaohe66.web.infrastructure.sec;

import com.xiaohe66.common.web.util.SecConst;
import com.xiaohe66.web.domain.account.value.AccountId;
import com.xiaohe66.web.domain.account.value.AccountName;
import com.xiaohe66.web.domain.sys.sec.entity.CurrentAccount;
import com.xiaohe66.web.domain.sys.sec.service.SecurityService;
import com.xiaohe66.web.domain.sys.sec.value.RoleName;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Component;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.Collections;
import java.util.HashSet;

/**
 * @author xiaohe
 * @since 2023.07.12 14:18
 */
@RequiredArgsConstructor
@ConditionalOnProperty(value = "xiaohe66.autologin.enable", havingValue = "true")
@Component
@Slf4j
public class DevAutoLoginFilter implements Filter {

    private final SecurityService securityService;
    private final SecAutoLoginConfig config;

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        log.info("init DevAutoLoginFilter, excludeUrl : {}", config.getExcludeUrl());
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        if (!securityService.isLogin()) {

            HttpServletRequest request = (HttpServletRequest) servletRequest;
            String uri = request.getRequestURI();

            if (!config.getExcludeUrl().contains(uri)) {

                log.info("dev auto login");
                try {

                    AccountId id = new AccountId(SecConst.ADMIN_ACCOUNT_ID);
                    AccountName name = new AccountName(SecConst.ADMIN_ACCOUNT_NAME);
                    RoleName roleName = new RoleName(SecConst.ADMIN_ACCOUNT_NAME);

                    CurrentAccount currentAccount = CurrentAccount.builder()
                            .id(id)
                            .name(name)
                            .roleNames(Collections.singleton(roleName))
                            .permissionNames(new HashSet<>())
                            .build();

                    securityService.login(currentAccount);
                    securityService.setCurrentAccount(currentAccount);

                    log.info("dev auto login success, account : {}", SecConst.ADMIN_ACCOUNT_NAME);

                } catch (Exception e) {

                    log.error("dev login error", e);
                }
            }
        }

        filterChain.doFilter(servletRequest, servletResponse);
    }
}
